package cn.wolfcde.luowowo.website.web.controller;

import cn.wolfcde.luowowo.website.annotation.RedisParameter;
import cn.wolfcode.luowowo.article.domain.Destination;
import cn.wolfcode.luowowo.article.domain.StrategyCommend;
import cn.wolfcode.luowowo.article.domain.StrategyDetail;
import cn.wolfcode.luowowo.article.domain.StrategyTag;
import cn.wolfcode.luowowo.article.query.StrategyDetailQuery;
import cn.wolfcode.luowowo.article.service.*;
import cn.wolfcode.luowowo.cache.service.IStrategyStatisticsService;
import cn.wolfcode.luowowo.cache.vo.StrategyStatisVO;
import cn.wolfcode.luowowo.comment.domain.StrategyComment;
import cn.wolfcode.luowowo.comment.query.StrategyCommentQueryObject;
import cn.wolfcode.luowowo.comment.service.IStrategyCommentService;
import cn.wolfcode.luowowo.common.domain.AjaxResult;
import cn.wolfcode.luowowo.common.key.RedisKey;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.search.query.StrategySearchQueryObject;
import cn.wolfcode.luowowo.search.service.IStrategyTemplateSearchService;
import cn.wolfcode.luowowo.search.template.StrategyTemplate;
import cn.wolfcode.luowowo.search.vo.StatisVO;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregation;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
import org.mockito.exceptions.misusing.NotAMockException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/strategy")
public class StrategyController {

    @Reference
    private IStrategyDetailService strategyDetailService;

    @Reference
    private IDestinationService destinationService;

    @Reference
    private IStrategyTagService strategyTagService;

    @Reference
    private IStrategyCommentService strategyCommentService;

    @Reference
    private IStrategyStatisticsService strategyStatisticsService;

    @Reference
    private IStrategyCommendService strategyCommendService;

    @Reference
    private IStrategyTemplateSearchService strategyTemplateSearchService;

    /**
     * 点击详情查看指定的攻略
     *
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("/detail")
    public String detail(Long id, Model model) {

        StrategyDetail strategyDetail = strategyDetailService.get(id);

        model.addAttribute("detail", strategyDetail);

        //添加阅读数
        strategyStatisticsService.addViewnum(id, 1);

        //获取到阅读数  页面要的是vo对象
        StrategyStatisVO strategyStatisVO = strategyStatisticsService.getStrategyStatisVO(id);

        model.addAttribute("vo", strategyStatisVO);

        //对热门排行对应name进行加值
        strategyStatisticsService.addScore(RedisKey.STRATEGY_STATIS_HOT_SORT.getPrefix(),
                RedisKey.STRATEGY_STATIS_VO.appendKey(id.toString()),
                1
        );

        return "strategy/detail";
    }

    /**
     * 查看全部攻略
     *
     * @param
     * @return
     */
    @RequestMapping("/list")
    public String list(@ModelAttribute("qo") StrategyDetailQuery qo, Model model) {

        List<Destination> toasts = destinationService.getToasts(qo.getDestId());
        toasts.remove(toasts.size() - 1);

        //toast
        model.addAttribute("toasts", toasts);

        //dest
        Destination dest = destinationService.selectById(qo.getDestId());
        model.addAttribute("dest", dest);

        //tags
        List<StrategyTag> tags = strategyTagService.list();
        model.addAttribute("tags", tags);

        //pageInfo
        PageInfo pageInfo = strategyDetailService.query(qo);
        model.addAttribute("pageInfo", pageInfo);


        return "strategy/list";
    }

    /**
     * 给攻略增加评论
     *
     * @param strategyComment
     * @param userInfo
     * @return
     */
    @RequestMapping("/commentAdd")
    @ResponseBody
    public AjaxResult commentAdd(StrategyComment strategyComment, @RedisParameter UserInfo userInfo, Model model) {

        AjaxResult ajaxResult = new AjaxResult();
        if (userInfo == null) {
            ajaxResult.mark("请登录后进行评论");

            return ajaxResult;
        }

        //拿出当前用户的信息 设置入
        strategyComment.setUserId(userInfo.getId());
        strategyComment.setUsername(userInfo.getNickname());
        strategyComment.setCity(userInfo.getCity());
        strategyComment.setLevel(userInfo.getLevel());
        strategyComment.setHeadUrl(userInfo.getHeadImgUrl());
        //调用方法
        strategyCommentService.commentAdd(strategyComment);

        //将对应的攻略下的评论数加一
        if (strategyComment.getDetailId() != null) {

            strategyDetailService.updateReplyNum(strategyComment.getDetailId(), 1);

            //需要传回一个评论的攻略的评论数
            int replyNum = strategyDetailService.getReplyNumById(strategyComment.getDetailId());

            ajaxResult.setResult(replyNum);

            //评论成功之后将redis中缓存的vo的评论数也加一
            strategyStatisticsService.addReplynum(strategyComment.getDetailId(), 1);

            //获取到评论数 页面要的是vo对象
            StrategyStatisVO strategyStatisVO = strategyStatisticsService.getStrategyStatisVO(strategyComment.getDetailId());

            model.addAttribute("vo", strategyStatisVO);

            //将热门排行中对应name进行加值
            strategyStatisticsService.addScore(RedisKey.STRATEGY_STATIS_HOT_SORT.getPrefix(),
                    RedisKey.STRATEGY_STATIS_VO.appendKey(strategyComment.getDetailId().toString()),
                    1);

        }

        return ajaxResult;
    }

    /**
     * 功略评论显示
     *
     * @param qo
     * @param model
     * @return
     */
    @RequestMapping("/comment")
    public String comment(@ModelAttribute("qo") StrategyCommentQueryObject qo, Model model) {

        //mongodb的分页查询
        Page page = strategyCommentService.queryPageForComment(qo);

        model.addAttribute("page", page);

        return "strategy/commentTpl";
    }

    /**
     * 给评论点赞
     *
     * @return
     */
    @RequestMapping("/commentThumbUp")
    @ResponseBody
    public AjaxResult commentThumbUp(String toid, Long fromid) {

        AjaxResult ajaxResult = new AjaxResult();

        StrategyComment strategyComment = strategyCommentService.strategyThumbup(toid, fromid);

        ajaxResult.setResult(strategyComment);

        return ajaxResult;
    }

    /**
     * 收藏
     *
     * @return
     */
    @RequestMapping("/favor")
    @ResponseBody
    public AjaxResult favor(Long sid, @RedisParameter UserInfo userInfo) {

        AjaxResult ajaxResult = new AjaxResult();

        if (userInfo == null) {

            ajaxResult.setCode(102);

            ajaxResult.mark("请登录后再进行收藏");

            return ajaxResult;
        }


        Boolean result = strategyStatisticsService.favor(sid, userInfo.getId());

        if (result == null) {

            ajaxResult.setCode(102);

            ajaxResult.mark("请登录后再进行收藏");

            return ajaxResult;
        }


        //获取到评论数 页面要的是vo对象
        StrategyStatisVO strategyStatisVO = strategyStatisticsService.getStrategyStatisVO(sid);

        ajaxResult.setSuccess(result);

        ajaxResult.setResult(strategyStatisVO);

        //根据点赞和收藏排序  给其排行依据加分   根据  收藏  和 取消 收藏 来进行 加分 和减分
        strategyStatisticsService.addScore(RedisKey.STRATEGY_STATIS_ISABROAD_SORT.getPrefix(),
                RedisKey.STRATEGY_STATIS_VO.appendKey(sid.toString()), result ? 1 : -1);


        return ajaxResult;
    }

    /**
     * 给攻略点赞
     *
     * @param sid
     * @param userInfo
     * @return
     */
    @RequestMapping("/strategyThumbup")
    @ResponseBody
    public AjaxResult strategyThumbup(Long sid, @RedisParameter UserInfo userInfo) {

        AjaxResult ajaxResult = new AjaxResult();

        if (userInfo == null) {

            ajaxResult.setCode(102);

            ajaxResult.mark("请登录后再进行点赞");

            return ajaxResult;
        }

        boolean result = strategyStatisticsService.strategyThumbup(sid, userInfo.getId());

        ajaxResult.setSuccess(result);

        //获取到评论数 页面要的是vo对象
        ajaxResult.setResult(strategyStatisticsService.getStrategyStatisVO(sid));

        //根据点赞和收藏排序  给其排行依据加分
        if (result) {
            strategyStatisticsService.addScore(RedisKey.STRATEGY_STATIS_ISABROAD_SORT.getPrefix(),
                    RedisKey.STRATEGY_STATIS_VO.appendKey(sid.toString()), 1);
        }

        return ajaxResult;

    }

    /**
     * 分享数+1
     *
     * @param sid
     * @return
     */
    @RequestMapping("/shareAdd")
    @ResponseBody
    public AjaxResult shareAdd(Long sid) {

        AjaxResult ajaxResult = new AjaxResult();

        //分享+1
        boolean flag = strategyStatisticsService.shareAdd(sid);

        if (flag) {

            //获取到评论数 页面要的是vo对象
            ajaxResult.setResult(strategyStatisticsService.getStrategyStatisVO(sid));

        }

        ajaxResult.setSuccess(flag);

        return ajaxResult;

    }

    /**
     * 攻略首页
     *
     * @return
     */
    @RequestMapping("")
    public String StrategyIndex(Model model) {


        //commends   获取前五篇推荐攻略回显到页面滚动播放
        List<StrategyCommend> commendsTop5 = strategyCommendService.getTop5();

        model.addAttribute("commends", commendsTop5);

        //abroadCds 海外攻略排行  unabroadCds  国内攻略排行 取出所有的排行vo数据
        List<StrategyStatisVO> vo_isabroad = strategyStatisticsService.getVOsBySort(RedisKey.STRATEGY_STATIS_ISABROAD_SORT.getPrefix(), 0, -1);

        //判断是国内还是国外
        List<StrategyStatisVO> abroadCds = new ArrayList<>();

        List<StrategyStatisVO> unabroadCds = new ArrayList<>();

        //分类获取国内国外的前10个vo数据
        for (StrategyStatisVO strategyStatisVO : vo_isabroad) {

            if (strategyStatisVO.isIsabroad()) {

                if (abroadCds.size() < 10) {

                    abroadCds.add(strategyStatisVO);
                }

            } else {

                if (unabroadCds.size() < 10) {

                    unabroadCds.add(strategyStatisVO);
                }
            }

        }
        //共享回页面
        model.addAttribute("abroadCds", abroadCds);
        model.addAttribute("unabroadCds", unabroadCds);

        //hotCds 热门攻略推荐回显,前十个
        List<StrategyStatisVO> hotCds = strategyStatisticsService.getVOsBySort(RedisKey.STRATEGY_STATIS_HOT_SORT.getPrefix(), 0, 9);

        model.addAttribute("hotCds", hotCds);


        //主题攻略推荐 ES实现
        List<StatisVO> theme_statisVOS = strategyTemplateSearchService.getGroupStatisVOS(StrategySearchQueryObject.THEME);

        //国内功略推荐 ES实现
        List<StatisVO> chinas_statisVOS = strategyTemplateSearchService.getGroupStatisVOS(StrategySearchQueryObject.CHINA);

        //国外攻略推荐 ES实现
        List<StatisVO> abroads_statisVOS = strategyTemplateSearchService.getGroupStatisVOS(StrategySearchQueryObject.ABROAD);

        //共享页面
        model.addAttribute("themes", theme_statisVOS);
        model.addAttribute("chinas", chinas_statisVOS);
        model.addAttribute("abroads", abroads_statisVOS);

        //主题推荐 取出主题推荐前10条返回页面  themeCds  数据结构  左边是主题的id 右边是主题下所有攻略会对应的目的地的集合
        List<Map<String, Object>> scd_top10 = strategyTemplateSearchService.getThemeCommedsTop10();

        model.addAttribute("themeCds", scd_top10);


        return "strategy/index";

    }


    /**
     * 功略推荐分页
     *
     * @return
     */
    @RequestMapping("/searchPage")
    public String searchPage(@ModelAttribute("qo") StrategySearchQueryObject qo, Model model) {

        //page
        Page page = strategyTemplateSearchService.query(qo);

        model.addAttribute("page", page);

        return "strategy/searchPageTpl";
    }

}
